﻿// Connect.cpp: CConnect 的实现

#include "pch.h"
#include "Connect.h"


// CConnect

namespace {
    HRESULT HrGetResource(int nId,
        LPCTSTR lpType,
        LPVOID* ppvResourceData,
        DWORD* pdwSizeInBytes)
    {
        HMODULE hModule = _AtlBaseModule.GetModuleInstance();
        if (!hModule)
            return E_UNEXPECTED;
        HRSRC hRsrc = FindResource(hModule, MAKEINTRESOURCE(nId), lpType);
        if (!hRsrc)
            return HRESULT_FROM_WIN32(GetLastError());
        HGLOBAL hGlobal = LoadResource(hModule, hRsrc);
        if (!hGlobal)
            return HRESULT_FROM_WIN32(GetLastError());
        *pdwSizeInBytes = SizeofResource(hModule, hRsrc);
        *ppvResourceData = LockResource(hGlobal);
        return S_OK;
    }

    BSTR GetXMLResource(int nId)
    {
        LPVOID pResourceData = NULL;
        DWORD dwSizeInBytes = 0;
        HRESULT hr = HrGetResource(nId, TEXT("XML"),
            &pResourceData, &dwSizeInBytes);
        if (FAILED(hr))
            return NULL;
        // Assumes that the data is not stored in Unicode.
        CComBSTR cbstr(dwSizeInBytes, reinterpret_cast<LPCSTR>(pResourceData));
        return cbstr.Detach();
    }

    SAFEARRAY* GetOFSResource(int nId)
    {
        LPVOID pResourceData = NULL;
        DWORD dwSizeInBytes = 0;
        if (FAILED(HrGetResource(nId, TEXT("OFS"),
            &pResourceData, &dwSizeInBytes)))
            return NULL;
        SAFEARRAY* psa;
        SAFEARRAYBOUND dim = { dwSizeInBytes, 0 };
        psa = SafeArrayCreate(VT_UI1, 1, &dim);
        if (psa == NULL)
            return NULL;
        BYTE* pSafeArrayData;
        SafeArrayAccessData(psa, (void**)&pSafeArrayData);
        memcpy((void*)pSafeArrayData, pResourceData, dwSizeInBytes);
        SafeArrayUnaccessData(psa);
        return psa;
    }
} // End of anonymous namespace

STDMETHODIMP_(HRESULT __stdcall) CConnect::OnConnection(LPDISPATCH Application, ext_ConnectMode ConnectMode, LPDISPATCH AddInInst, SAFEARRAY** custom)
{
    //::MessageBoxW(NULL, L"OnConnection", L"Native PPT Addin", MB_OK);
    // 保存Application对象
    //Application->QueryInterface(__uuidof(PowerPoint::_Application), (void**)&m_pPPTApp);
    //m_pPPTApp = Application;
    //m_pPPTApp = NULL;
    //if (Application)
    //    Application->QueryInterface(__uuidof(PowerPoint::_Application), (void**)&m_pPPTApp);
    m_pPPTApp = CComQIPtr<PowerPoint::_Application>(Application);

    return S_OK;

}

STDMETHODIMP_(HRESULT __stdcall) CConnect::GetCustomUI(BSTR RibbonID, BSTR* RibbonXml)
{
    if (!RibbonXml)
        return E_POINTER;
    *RibbonXml = GetXMLResource(IDR_XML1); // 添加的资源文件
    return S_OK;
}

//STDMETHODIMP_(HRESULT __stdcall) CConnect::ButtonClicked(IDispatch* ribbon)
//{
//    if (!m_pPPTApp)
//        return E_FAIL;
//
//    CComQIPtr<IRibbonControl> ribbonCtl(ribbon);
//    CComBSTR idStr;
//
//    if (ribbonCtl->get_Id(&idStr) != S_OK)
//        return S_FALSE;
//
//    HRESULT hr = S_OK;
//
//    if (idStr == OLESTR("countButton")) {
//        // 获取当前演示文稿
//        CComPtr<PowerPoint::_Presentation> spPresentation;
//        hr = m_pPPTApp->get_ActivePresentation(&spPresentation);
//        if (FAILED(hr))
//            return hr;
//
//        // 获取当前幻灯片
//        CComPtr<PowerPoint::_Slide> spSlide;
//        //CComPtr<PowerPoint::Selection> spSelection;
//        //hr = m_pPPTApp->get_ActiveWindow(&spSelection);
//        //CComPtr<PowerPoint::SlideShowWindow> spSSW;
//        //hr = m_pPPTApp->get_SlideShowWindows(&spSSW);
//        //if (SUCCEEDED(hr)) {
//        //    CComPtr<PowerPoint::SlideRange> spSlideRange;
//        //    hr = spSelection->get_SlideRange(&spSlideRange);
//        //    if (SUCCEEDED(hr)) {
//        //        hr = spSlideRange->Item(CComVariant(1), &spSlide);
//        //    }
//        //}
//        CComPtr<PowerPoint::DocumentWindow> spDocWin;
//        hr = m_pPPTApp->get_ActiveWindow(&spDocWin);
//        if (SUCCEEDED(hr) && spDocWin) {
//            CComPtr<PowerPoint::View> spView;
//            hr = spDocWin->get_View(&spView);
//            CComPtr<PowerPoint::_Slide> spSlide;
//            if (SUCCEEDED(hr) && spView) {
//                CComPtr<IDispatch> spSlideDisp;
//                hr = spView->get_Slide(&spSlideDisp);
//                //hr = spView->get_Slide(&spSlide);
//                // spSlide 就是当前幻灯片
//            }
//        }
//
//        if (FAILED(hr))
//            return hr;
//
//        // 获取幻灯片中的所有形状
//        CComPtr<PowerPoint::Shapes> spShapes;
//        hr = spSlide->get_Shapes(&spShapes);
//        if (FAILED(hr))
//            return hr;
//
//        long count = 0;
//        int totalShapes = 0;
//        spShapes->get_Count(&totalShapes);
//
//        // 遍历所有形状，计算非空文本框的数量
//        for (long i = 1; i <= totalShapes; i++) {
//            CComPtr<PowerPoint::Shape> spShape;
//            if (SUCCEEDED(spShapes->Item(CComVariant(i), &spShape))) {
//                CComPtr<PowerPoint::TextFrame> spTextFrame;
//                if (SUCCEEDED(spShape->get_TextFrame(&spTextFrame))) {
//                    CComPtr<PowerPoint::TextRange> spTextRange;
//                    if (SUCCEEDED(spTextFrame->get_TextRange(&spTextRange))) {
//                        CComBSTR text;
//                        if (SUCCEEDED(spTextRange->get_Text(&text)) && text.Length() > 0) {
//                            count++;
//                        }
//                    }
//                }
//            }
//        }
//
//        // 显示结果
//        WCHAR msg[64];
//        swprintf_s(msg, L"当前幻灯片中共有 %d 个非空文本框", count);
//        MessageBoxW(NULL, msg, L"统计结果", MB_OK);
//    }
//    else if (idStr == OLESTR("editButton")) {
//        // 获取当前演示文稿
//        CComPtr<PowerPoint::_Presentation> spPresentation;
//        hr = m_pPPTApp->get_ActivePresentation(&spPresentation);
//        if (FAILED(hr))
//            return hr;
//
//        // 获取幻灯片集合
//        CComPtr<PowerPoint::Slides> spSlides;
//        hr = spPresentation->get_Slides(&spSlides);
//        if (FAILED(hr))
//            return hr;
//
//        long slideCount = 0;
//        spSlides->get_Count(&slideCount);
//
//        // 添加新的幻灯片
//        CComPtr<PowerPoint::_Slide> spNewSlide;
//        hr = spSlides->Add(slideCount + 1, ppLayoutText, &spNewSlide);
//        if (FAILED(hr))
//            return hr;
//
//        CComPtr<PowerPoint::ShapeRange> spBgShapeRange;
//        hr = spNewSlide->get_Background(&spBgShapeRange);
//        if (SUCCEEDED(hr) && spBgShapeRange) {
//            CComPtr<PowerPoint::FillFormat> spFill;
//            hr = spBgShapeRange->get_Fill(&spFill);
//            if (SUCCEEDED(hr) && spFill) {
//                // 主题色着色1通常为 ppSchemeColorAccent1
//                // 但 MsoThemeColorIndex 取值需查 MSDN, 通常是 ppThemeColorAccent1 = 5
//                spFill->put_ForeColor->put_SchemeColor(5 /*ppThemeColorAccent1*/);
//            }
//        }
//
//        MessageBoxW(NULL, L"已添加新幻灯片并设置背景色", L"操作成功", MB_OK);
//    }
//
//    return S_OK;
//}

// Connect.cpp
STDMETHODIMP CConnect::ButtonClicked(IDispatch* ribbon)
{
    if (!m_pPPTApp)
        return E_FAIL;

    CComQIPtr<IRibbonControl> ribbonCtl(ribbon);
    CComBSTR idStr;

    if (ribbonCtl->get_Id(&idStr) != S_OK)
        return S_FALSE;

    HRESULT hr = S_OK;

    if (idStr == OLESTR("countButton")) {
        // 获取当前演示文稿
        CComPtr<PowerPoint::_Presentation> spPresentation;
        hr = m_pPPTApp->get_ActivePresentation(&spPresentation);
        if (FAILED(hr))
            return hr;

        // 获取当前幻灯片
        CComPtr<PowerPoint::DocumentWindow> spDocWin;
        hr = m_pPPTApp->get_ActiveWindow(&spDocWin);
        if (SUCCEEDED(hr) && spDocWin) {
            CComPtr<PowerPoint::View> spView;
            hr = spDocWin->get_View(&spView);
            if (SUCCEEDED(hr) && spView) {
                // 注意这里的修改，使用 IDispatch* 作为中间类型
                CComPtr<IDispatch> spSlideDisp;
                hr = spView->get_Slide(&spSlideDisp);
                if (SUCCEEDED(hr) && spSlideDisp) {
                    // 转换为 _Slide 接口
                    CComPtr<PowerPoint::_Slide> spSlide;
                    hr = spSlideDisp->QueryInterface(__uuidof(PowerPoint::_Slide), (void**)&spSlide);
                    if (SUCCEEDED(hr) && spSlide) {
                        // 获取幻灯片中的所有形状
                        CComPtr<PowerPoint::Shapes> spShapes;
                        hr = spSlide->get_Shapes(&spShapes);
                        if (SUCCEEDED(hr) && spShapes) {
                            int totalShapes = 0;
                            spShapes->get_Count(&totalShapes);

                            // 遍历所有形状，计算非空文本框的数量
                            int count = 0;
                            for (int i = 1; i <= totalShapes; i++) {
                                CComPtr<PowerPoint::Shape> spShape;
                                if (SUCCEEDED(spShapes->Item(CComVariant(i), &spShape))) {
                                    CComPtr<PowerPoint::TextFrame> spTextFrame;
                                    if (SUCCEEDED(spShape->get_TextFrame(&spTextFrame))) {
                                        CComPtr<PowerPoint::TextRange> spTextRange;
                                        if (SUCCEEDED(spTextFrame->get_TextRange(&spTextRange))) {
                                            CComBSTR text;
                                            if (SUCCEEDED(spTextRange->get_Text(&text)) && text.Length() > 0) {
                                                count++;
                                            }
                                        }
                                    }
                                }
                            }

                            // 显示结果
                            WCHAR msg[64];
                            swprintf_s(msg, L"当前幻灯片中共有 %d 个非空文本框", count);
                            MessageBoxW(NULL, msg, L"统计结果", MB_OK);
                        }
                    }
                }
            }
        }
    }
    else if (idStr == OLESTR("editButton")) {
        // 获取当前演示文稿
        CComPtr<PowerPoint::_Presentation> spPresentation;
        hr = m_pPPTApp->get_ActivePresentation(&spPresentation);
        if (FAILED(hr))
            return hr;

        // 获取幻灯片集合
        CComPtr<PowerPoint::Slides> spSlides;
        hr = spPresentation->get_Slides(&spSlides);
        if (FAILED(hr))
            return hr;

        long slideCount = 0;
        spSlides->get_Count(&slideCount);

        // 添加新的幻灯片
        CComPtr<PowerPoint::_Slide> spNewSlide;
        hr = spSlides->Add(slideCount + 1, ppLayoutText, &spNewSlide);
        if (FAILED(hr))
            return hr;

        // 设置背景色为主题色着色 1
        CComPtr<PowerPoint::ShapeRange> spBgShapeRange;
        hr = spNewSlide->get_Background(&spBgShapeRange);
        if (SUCCEEDED(hr) && spBgShapeRange) {
            CComPtr<PowerPoint::FillFormat> spFill;
            hr = spBgShapeRange->get_Fill(&spFill);
            if (SUCCEEDED(hr) && spFill) {
                // 获取 ForeColor
                CComPtr<PowerPoint::ColorFormat> spColor;
                hr = spFill->get_ForeColor(&spColor);
                if (SUCCEEDED(hr) && spColor) {
                    // 设置主题色
                    spColor->put_SchemeColor(ppAccent1);
                    //spColor->put_ObjectThemeColor(msoThemeAccent1);
                }
            }
        }

        MessageBoxW(NULL, L"已添加新幻灯片并设置背景色", L"操作成功", MB_OK);
    }

    return S_OK;
}

